import libtcodpy as libtcod
import make_map
from tile import Tile
from object import Object

SCREEN_WIDTH = 80
SCREEN_HEIGHT = 50
LIMIT_FPS = 20

libtcod.console_set_custom_font('arial12x12.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
libtcod.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT, 'PokeRL', False)

con = libtcod.console_new(SCREEN_WIDTH, SCREEN_HEIGHT)

# Map
MAP_WIDTH = 80
MAP_HEIGHT = 45

color_dark_wall = libtcod.Color(50, 50, 40)
color_dark_ground = libtcod.Color(80, 80, 60)

color_light_wall = libtcod.Color(130, 110, 50)
color_light_ground = libtcod.Color(180, 150, 40)

color_unexplored = libtcod.black

FOV_ALGO = 0
FOV_LIGHT_WALLS = True
TORCH_RADIUS = 6



# Input
def handle_keys():
    global player

    key = libtcod.console_check_for_keypress(True)
    while key.vk == 0:
        key = libtcod.console_check_for_keypress(True)

    # Fullscreen
    if key.vk == libtcod.KEY_ENTER and key.lalt:
        libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
    # Quit
    elif key.vk == libtcod.KEY_ESCAPE:
        return 'exit'

    # Movement:
    elif game_state == 'playing':
        # Cursor keys
        if key.vk == libtcod.KEY_UP:    player_move_or_attack(0,-1)
        elif key.vk == libtcod.KEY_DOWN:  player_move_or_attack(0,+1)
        elif key.vk == libtcod.KEY_LEFT:  player_move_or_attack(-1,0)
        elif key.vk == libtcod.KEY_RIGHT: player_move_or_attack(+1,0)
        
        # Numpad keys
        elif key.vk == libtcod.KEY_KP1: player_move_or_attack(-1,+1)
        elif key.vk == libtcod.KEY_KP2: player_move_or_attack( 0,+1)
        elif key.vk == libtcod.KEY_KP3: player_move_or_attack(+1,+1)
        elif key.vk == libtcod.KEY_KP4: player_move_or_attack(-1, 0)
        elif key.vk == libtcod.KEY_KP6: player_move_or_attack(+1, 0)
        elif key.vk == libtcod.KEY_KP7: player_move_or_attack(-1,-1)
        elif key.vk == libtcod.KEY_KP8: player_move_or_attack( 0,-1)
        elif key.vk == libtcod.KEY_KP9: player_move_or_attack(+1,-1)
        
        # vi-keys
        elif key.vk == libtcod.KEY_CHAR:
            if key.c == ord('h'): player_move_or_attack(-1, 0)
            if key.c == ord('j'): player_move_or_attack( 0,+1)
            if key.c == ord('k'): player_move_or_attack( 0,-1)
            if key.c == ord('l'): player_move_or_attack(+1, 0)
            if key.c == ord('y'): player_move_or_attack(-1,-1)
            if key.c == ord('u'): player_move_or_attack(+1,-1)
            if key.c == ord('b'): player_move_or_attack(-1,+1)
            if key.c == ord('n'): player_move_or_attack(+1,+1)
            
    # No input
    else:
        player_action = 'didnt-take-turn'
                


def player_move_or_attack( dx, dy ):
    x = player.x + dx
    y = player.y + dy
    if len( map[x][y].objects ) > 0:
        print('You use Struggle against ' + map[x][y].objects[0].name)
    else:
        player.move(dx,dy)



# Rendering
def render_all():
    # Draw objects
    for object in objects:
        if libtcod.map_is_in_fov(fov_map, object.x, object.y):
            object.draw(con)

    # Draw map
    for x in range(MAP_WIDTH):
        for y in range(MAP_HEIGHT):
            if libtcod.map_is_in_fov(fov_map, x, y):
                map[x][y].explore()
                if map[x][y].block_sight:
                    libtcod.console_set_char_background(con, x, y, color_light_wall, libtcod.BKGND_SET)
                else:
                    libtcod.console_set_char_background(con, x, y, color_light_ground, libtcod.BKGND_SET)
            else:
                if map[x][y].explored:
                    if map[x][y].block_sight:
                        libtcod.console_set_char_background(con, x, y, color_dark_wall, libtcod.BKGND_SET)
                    else:
                        libtcod.console_set_char_background(con, x, y, color_dark_ground, libtcod.BKGND_SET)
                else:
                    libtcod.console_set_char_background(con, x, y, color_unexplored, libtcod.BKGND_SET)

    libtcod.console_blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0)
    libtcod.console_flush()



# Global initialisations
objects = []
map = make_map.get_map(MAP_WIDTH, MAP_HEIGHT, objects)
player = Object(MAP_WIDTH/2, MAP_HEIGHT/2, "Player", '@', libtcod.white, True, map)
objects.append( player )

game_state = 'playing'
player_action = None

# Lighting map
fov_map = libtcod.map_new(MAP_WIDTH, MAP_HEIGHT)
for x in range(MAP_WIDTH):
    for y in range(MAP_HEIGHT):
        libtcod.map_set_properties(fov_map, x, y, not map[x][y].block_sight, not map[x][y].wall)



# Main loop
while not libtcod.console_is_window_closed():
    libtcod.map_compute_fov(fov_map, player.x, player.y, TORCH_RADIUS, FOV_LIGHT_WALLS, FOV_ALGO)
    render_all()

    for object in objects:
        object.clear(con)

    player_action = handle_keys()
    if player_action == 'exit':
        break

    # Monster turn
    if game_state == 'playing' and player_action != 'didnt-take-turn':
        for object in objects:
            if object != player:
                print( object.name + ' growls!' )
